$(document).ready(canvasApp);

function canvasSupport () {
     return Modernizr.canvas;
}

function canvasApp() {

   if (!canvasSupport()) {
          return;
     }else{
	 
      var theCanvas = document.getElementById("canvas");
      var context = theCanvas.getContext("2d");
	 
	  var guiCanvas = document.getElementById("gui");
      var guiCtx = guiCanvas.getContext("2d");
	  
	  var button = document.images["jsbutton"];
	  
	  startUp();
   }
   
	var photo = new Image();
	var smallMap = new Image();
	var atkButton = new Image();
	var sprite = new Image();
	var sprite2 = new Image();
	var dot = new Image();
	dot.src="reddot.png";
	var bluedot = new Image();
	bluedot.src="bluedot.png"
	var rep_red = new Image();
	rep_red.src="reptile_red.png";
	var rep_blue = new Image();
	rep_blue.src="reptile_blue.png";
	sprite.src="reptile.png";
	sprite2.src="reddot.png";
	//replace with tilesize
	photo.src = "bigmap.png";
	smallMap.src="map.png";
	atkButton.src="attack.png"
	var windowWidth = theCanvas.width;
	var windowHeight = theCanvas.height;
	var windowX = 0;
	var windowY = 0;

	var currentScale = 1;
	var minScale = .2;
	var maxScale = 3;
	var scaleIncrement = .1;

	var mouseStartX=0;
	var mouseStartY=0;
	var mouseEndX=0;
	var mouseEndY=0;

	var startRect;

	var destX=0;
	var destY=0;
	var speedX=5;
	var speedY=5;

	var gameObjects = {};
	var selected = [];
	//gameObjects[unit1.id] = unit1;
	//gameObjects[unit2.id] = unit2;
	
	var mmDrag=0;
	
	var myPlayerId;

	//websocket stuff starts here ------------------------------------------------------------
	var ip = "127.0.0.1";
	var ws;

	if(typeof MozWebSocket !== "undefined") {
		ws = new MozWebSocket('ws://'+ip+':8181/4911-game', 'post');
	}
	else {
		ws = new WebSocket('ws://'+ip+':8181/4911-game', 'post');
	}

	ws.onopen = function () {
		ws.send(String.fromCharCode(1));
	};
	ws.onclose = function() {
	};
	ws.onerror = function (event) {
	}
	ws.onmessage = function (event) {
		var messageType=event.data.charCodeAt(0);
		switch(messageType){
			case 1:
				updateWorld(event.data);
				break;
			case 0:
				myPlayerId = event.data.charCodeAt(1);
				console.log(myPlayerId);
				break;
			//chat message
			case 3:
				$('#chat_log').html($('#chat_log').html() + '<br/>' + event.data.substr(1));
				break;
		}
	};

	function sendMove(x, y, selection){
		var msgString=String.fromCharCode(2)+String.fromCharCode(x)+String.fromCharCode(y)+String.fromCharCode(selection.length);

		for(var i=0;i<selection.length;i++){
			msgString+=String.fromCharCode(selection[i].id);
		}
		ws.send(msgString);
		console.log(msgString+","+x);
	}
	
	function sendBuild(type, x, y){
		var msgString=String.fromCharCode(1)+String.fromCharCode(type)+String.fromCharCode(x)+String.fromCharCode(y);
		
		ws.send(msgString);
	}

	function sendChatMessage() {
                var msg = $('#chat_input').val();
		if(msg.length > 0) {
                        ws.send(String.fromCharCode(3) + msg);
                        $('#chat_input').val('');
		}
        }
	
	function toCharCodes(data) {
		var retString = '';
		for(var i = 0; i < data.length; i++) {
			retString += data.charCodeAt(i) + ', ';
		}
		return retString;
	}
	//websocket stuff ends here---------------------------------------------------------------------------------------


	theCanvas.addEventListener('mousedown', eventMouseDown, false);
	theCanvas.addEventListener('mousemove', eventMouseMove, false);
	theCanvas.addEventListener('mouseup',   eventMouseUp, false);
	
	guiCanvas.addEventListener('mousedown', mmEventMouseDown, false);
	guiCanvas.addEventListener('mousemove', mmEventMouseMove, false);
	guiCanvas.addEventListener('mouseup',   mmEventMouseUp, false);
	
	function mmEventMouseDown(event){
		
		
		if (event.which==3){
			destX = event.layerX*128*32/200;
			destY = event.layerY*128*32/200;
			startRect=false;
			sendMove(destX/32, destY/32, selected);
		}else{
			var mmX = event.layerX;
			var mmY = event.layerY;
			
			mmX = mmX - (1000/(128*32/200))/2;
			mmY = mmY - (800/(128*32/200))/2;
			
			windowX = (mmX*128*32)/200;
			windowY = (mmY*128*32)/200;
			
			if (windowY<0){
					   windowY = 0;
			}

			if (windowY>photo.height - windowHeight){
					   windowY = photo.height - windowHeight;
			}

			if (windowX<0){
					   windowX = 0;
			}

			if (windowX>photo.width - windowWidth){
					   windowX = photo.width - windowWidth;
			}
			
			mmDrag=1;
		}
		
	}
	
	function mmEventMouseMove(event){
		
		if (mmDrag==1){
			var mmX = event.layerX;
			var mmY = event.layerY;
			
			mmX = mmX - (1000/(128*32/200))/2;
			mmY = mmY - (800/(128*32/200))/2;
			
			windowX = (mmX*128*32)/200;
			windowY = (mmY*128*32)/200;
			
			if (windowY<0){
					   windowY = 0;
			}

			if (windowY>photo.height - windowHeight){
					   windowY = photo.height - windowHeight;
			}

			if (windowX<0){
					   windowX = 0;
			}

			if (windowX>photo.width - windowWidth){
					   windowX = photo.width - windowWidth;
			}
		}
	}
	
	function mmEventMouseUp(event){
		mmDrag=0;
	}


	function eventMouseDown(event) {
		mouseStartX = event.layerX;
		mouseStartY = event.layerY;
		//theCanvas.width = theCanvas.width;
		//	  context.strokeRect(mouseStartX,mouseStartY,300,500);
		startRect = true;
		if (event.which==3){
			destX = event.layerX + windowX;
			destY = event.layerY + windowY;
			console.log("destination is" + destX + "," + destY);
		
			for (var i=0; i<selected.length; i++)
			{
				console.log(selected[i].id+","+selected[i].x+","+selected[i].y);
			}
			//console.log("currentpos is" + go.x + "," + go.y);
			startRect=false;
			sendMove(destX/32, destY/32, selected);
		}
	}

	function eventMouseMove(event) {
		mouseEndX=event.layerX;
		mouseEndY=event.layerY;
	}

	function eventMouseUp(event) {
		switch(event.which)
		{
			// left mouse button
			case 1:
				for(var goId in gameObjects) {
					var go = gameObjects[goId];
					if(go.x+16<mouseEndX && go.x+16>mouseStartX){
						if((go.y+16<mouseEndY && go.y+16>mouseStartY) || (go.y+16>mouseEndY && go.y+16<mouseStartY)){
							if (go.playerId == myPlayerId){
								selected.push(go);
							}
						}
					}
					if(go.x+16>mouseEndX && go.x+16<mouseStartX){
						if((go.y+16<mouseEndY && go.y+16>mouseStartY) || (go.y+16>mouseEndY && go.y+16<mouseStartY)){
							if (go.playerId == myPlayerId){
								selected.push(go);
							}
						}
					}
				}
				startRect = false;
				break;		
		}
	}


	function updateWorld(gState)
	{
		//console.log(toCharCodes(gState));
		var i = 2;
		for(;i<gState.charCodeAt(1)*6+2;i+=6)	{
			var id=gState.charCodeAt(i);
			var type=gState.charCodeAt(i+1);
			var pID=gState.charCodeAt(i+2);
			var x=gState.charCodeAt(i+3);
			var y=gState.charCodeAt(i+4);
			var hp=gState.charCodeAt(i+5);
			if (pID==0){
				gameObjects[gState.charCodeAt(i)] =new unit(x,y,rep_blue,hp,id,pID,type,0,0,0,0,1);
			}
			if (pID==1){
				gameObjects[gState.charCodeAt(i)] =new unit(x,y,rep_red,hp,id,pID,type,0,0,0,0,1);
			}
		}
		var oldStart = i;
		i++;
		for(; i < gState.charCodeAt(oldStart)*4+oldStart; i+=4) {
			var go = gameObjects[gState.charCodeAt(i)];
			go.x=go.xNext;
			go.y=go.yNext;
			go.xNext=gState.charCodeAt(i+1);//xNext is used to smooth the movement. maybe should not be in the object, but whatever for now
			go.yNext=gState.charCodeAt(i+2);
			go.hp=gState.charCodeAt(i+3);
		}
		var deadStart = i;
		i++;
		var derp = gState.charCodeAt(deadStart) + deadStart;
		for(; i <= gState.charCodeAt(deadStart) + deadStart; i++) {
			console.log(gState.charCodeAt(i));
			selected.splice(selected.indexOf(gameObjects[gState.charCodeAt(i)]),1);
			delete gameObjects[gState.charCodeAt(i)];
		}
	
	}
	
	//the smooth function smooths movement between updates
	//todo: speed
	function smooth(goId){
		if	(gameObjects[goId].xNext>gameObjects[goId].x){
			gameObjects[goId].x=gameObjects[goId].x+gameObjects[goId].speed;
		}
		else if (gameObjects[goId].xNext<gameObjects[goId].x){
		gameObjects[goId].x=gameObjects[goId].x-gameObjects[goId].speed;
		}
		
		if	(gameObjects[goId].yNext>gameObjects[goId].y){
			gameObjects[goId].y=gameObjects[goId].y+gameObjects[goId].speed;
		}
		else if (gameObjects[goId].yNext<gameObjects[goId].y){
		gameObjects[goId].y=gameObjects[goId].y-gameObjects[goId].speed;
		}
	}

	function drawScreen() {
		context.fillRect(0,0,theCanvas.width,theCanvas.height);
		guiCtx.fillStyle = "#000000";
		guiCtx.fillRect(0,0,guiCanvas.width,guiCanvas.height);
		/*for(var i=0;i<selected.length;i++){
			if(destX != -1 && destY != -1){
				if (selected[i].x<destX){
					prevX = selected[i].x;
					selected[i].x+=speedX;
					for(var j=0;j<gameObjects.length;j++){
						if(gameObjects[j] != selected[i] && selected.indexOf(gameObjects[j]) == -1){
							if (selected[i].x>gameObjects[j].x - 16 && selected[i].x<gameObjects[j].x + 16 && selected[i].y<gameObjects[j].y + 16 && selected[i].y>gameObjects[j].y - 16){
								destX = prevX;}}}}
				if (selected[i].x>destX){
					prevX = selected[i].x;
					selected[i].x-=speedX;
					for(var j=0;j<gameObjects.length;j++){
						if(gameObjects[j] != selected[i] && selected.indexOf(gameObjects[j]) == -1){
							if (selected[i].x>gameObjects[j].x - 16 && selected[i].x<gameObjects[j].x + 16 && selected[i].y<gameObjects[j].y + 16 && selected[i].y>gameObjects[j].y - 16){
								destX = prevX;}}}}
				if (selected[i].y<destY){
					prevY = selected[i].y;
					selected[i].y+=speedY;
					for(var j=0;j<gameObjects.length;j++){
						if(gameObjects[j] != selected[i] && selected.indexOf(gameObjects[j]) == -1){
							if (selected[i].x>gameObjects[j].x - 16 && selected[i].x<gameObjects[j].x + 16 && selected[i].y<gameObjects[j].y + 16 && selected[i].y>gameObjects[j].y - 16){
								destY = prevY;}}}}
				if (selected[i].y>destY){
					prevY = selected[i].y;
					selected[i].y-=speedY;
					for(var j=0;j<gameObjects.length;j++){
						if(gameObjects[j] != selected[i] && selected.indexOf(gameObjects[j]) == -1){
							if (selected[i].x>gameObjects[j].x - 16 && selected[i].x<gameObjects[j].x + 16 && selected[i].y<gameObjects[j].y + 16 && selected[i].y>gameObjects[j].y - 16){
								destY = prevY;}}}}}}*/


		context.drawImage(photo, windowX, windowY, windowWidth, windowHeight, 0, 0, windowWidth*currentScale,windowHeight*currentScale);
		drawGui();
		context.lineWidth = 2;
		context.strokeStyle = "#33FF00";
		for(var goId in gameObjects){
			var go = gameObjects[goId];
			smooth(goId);
			context.drawImage(go.img, go.x-windowX, go.y-windowY);
			
			if (go.playerId == 0){
				guiCtx.drawImage(bluedot, go.x/(128*32/200), go.y/(128*32/200));
			}else if (go.playerId == 1){
				guiCtx.drawImage(dot, go.x/(128*32/200), go.y/(128*32/200));
			}
			
			//the red bar
			context.strokeStyle = "#FF0000";
			context.lineWidth=2;
			context.lineCap='square';
			context.beginPath();
			context.moveTo(go.x-windowX, go.y-windowY+40);
			context.lineTo(go.x-windowX+32, go.y-windowY+40);
			context.stroke();
			context.closePath();
			//the green bar
			context.strokeStyle = "#33FF00";
			context.lineWidth=2;
			context.lineCap='square';
			context.beginPath();
			context.moveTo(go.x-windowX, go.y-windowY+40);
			var hpbar;
			hpbar=go.hp/go.maxhp*32;
			context.lineTo(go.x-windowX+hpbar, go.y-windowY+40);
			context.stroke();
			context.closePath();
			//end hp bar
			if(selected.indexOf(go) != -1){
				context.strokeRect(go.x-windowX, go.y-windowY, 32,32);
			}
			if (startRect) {
				destX = -1;
				destY = -1;
				selected = [];
				context.lineWidth = 3;
				context.strokeStyle = "#33FF00";
				context.strokeRect(mouseStartX,mouseStartY,mouseEndX-mouseStartX,mouseEndY-mouseStartY);
			}
		}
	}
	function drawMinimap(){
		//uses the smaller image
		guiCtx.drawImage(smallMap,0,0,200,200);
		
		//viewport
		guiCtx.strokeStyle = "#FF0000";
		guiCtx.linewidth=1;
		guiCtx.strokeRect(windowX/(128*32/200),windowY/(128*32/200),1000/(128*32/200), 800/(128*32/200));
		
	}
	
	function drawGui(){
		guiCtx.fillStyle = "#000000";
		guiCtx.fillRect(0, windowHeight - windowHeight/4, windowWidth, windowHeight/4);
		guiCtx.strokeStyle = "#FFFFFF";
		guiCtx.linewidth=1;
		guiCtx.fillStyle = "#73FF00";
		guiCtx.strokeRect(700, 0, 300, 200);
		if (selected.length > 0){
			if (selected[0].speed == 0){
				guiCtx.drawImage(selected[0].img, 410, 100, 64, 64);
				guiCtx.fillText("HP: " + selected[0].hp, 410, 134);
				guiCtx.drawImage(sprite,710,10,50,50);}
			else{
				for(var i=0;i<selected.length;i++){
					guiCtx.drawImage(selected[i].img, 210 + i*42, 15, 32, 32);
					guiCtx.fillText("HP: " + selected[i].hp, 210 + i*42, 52);
					if (i >= 10){
						i = selected.length;}
					}
				guiCtx.drawImage(atkButton,710,10,50,50);
				}
			}
		drawMinimap();
	}

	function drawHP(){
	
	}
	
	function startUp(){
		setInterval(drawScreen, 1000/60 );
	}

	theCanvas.oncontextmenu=function(){
		return false
	}
	
	guiCanvas.oncontextmenu=function(){
		return false
	}
	
	
	document.onkeydown = function(e){
		e = e?e:window.event;
		console.log(e.keyCode + "down");
		switch (e.keyCode){
		  case 87:
				//up
				windowY-=10;
				if (windowY<0){
				   windowY = 0;
				}
				break;
		  case 83:
				//down
				windowY+=10;
				if (windowY>photo.height - windowHeight){
				   windowY = photo.height - windowHeight;
				}
				break;
		  case 65:
				//left
				windowX-=10;
				if (windowX<0){
				   windowX = 0;
				}
				break;
		  case 68:
				//right
				windowX+=10;
				if (windowX>photo.width - windowWidth){
				   windowX = photo.width - windowWidth;
				}
				break;
		  case 109:
				//-
				currentScale-=scaleIncrement;
				if (currentScale<minScale){
				   currentScale = minScale;
				}
				break;
		 case 107:
				//+
				currentScale+=scaleIncrement;
				if (currentScale>maxScale){
				   currentScale = maxScale;
                                }
                                break;
		case 70:
                                sendBuild(2,10,10);
                                break;
                }
	}

        $('#chat_input').keypress(function(event) {
		switch(event.which) {
			case 13:
				sendChatMessage();
				break;
		}
	});
}

